package com.edu.exam.entity.curriculum.questionbank;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;

/**
 * 试题版本控制实体类
 * 对应数据库表：question_versions
 *
 * 管理试题的版本信息，包括版本号、变更内容、变更原因等。
 * 支持试题版本的创建、查询、比较和回滚。
 * 关联试题、变更人等关键信息，提供试题版本的完整视图。
 *
 * @author System
 * @version 1.0.0
 */
@Entity
@Comment("试题版本控制表")
@SQLDelete(sql = "UPDATE question_versions SET is_deleted = true, delete_time = CURRENT_TIMESTAMP WHERE id = ?")
@Where(clause = "is_deleted = false")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class QuestionVersion {

    /**
     * 版本唯一标识符
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    
    private Long id;

    /**
     * 试题ID
     */
    @NotNull(message = "试题ID不能为空")
    @Column(name = "question_id", nullable = false)
    private Long questionId;

    /**
     * 版本号
     */
    @NotNull(message = "版本号不能为空")
    @Column(name = "version_number", nullable = false)
    private Integer versionNumber;

    /**
     * 版本名称
     */
    @Size(max = 100, message = "版本名称长度不能超过100个字符")
    @Column(name = "version_name", length = 100)
    private String versionName;

    /**
     * 版本类型
     */
    @NotNull(message = "版本类型不能为空")
    @Enumerated(EnumType.STRING)
    @Column(name = "version_type", nullable = false, length = 20)
    private VersionType versionType;

    /**
     * 版本状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "version_status", nullable = false, length = 20)
    private VersionStatus versionStatus;

    /**
     * 变更类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "change_type", length = 20)
    private ChangeType changeType;

    /**
     * 变更原因
     */
    @Size(max = 1000, message = "变更原因长度不能超过1000个字符")
    @Column(name = "change_reason", length = 1000)
    private String changeReason;

    /**
     * 变更说明
     */
    @Size(max = 2000, message = "变更说明长度不能超过2000个字符")
    @Column(name = "change_description", length = 2000)
    private String changeDescription;

    /**
     * 变更人
     */
    @Size(max = 50, message = "变更人长度不能超过50个字符")
    @Column(name = "changed_by", nullable = false, length = 50)
    private String changedBy;

    /**
     * 审核人
     */
    @Size(max = 50, message = "审核人长度不能超过50个字符")
    @Column(name = "reviewed_by", length = 50)
    private String reviewedBy;

    /**
     * 审核状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "review_status", length = 20)
    private ReviewStatus reviewStatus;

    /**
     * 审核意见
     */
    @Size(max = 1000, message = "审核意见长度不能超过1000个字符")
    @Column(name = "review_comment", length = 1000)
    private String reviewComment;

    /**
     * 审核时间
     */
    @Column(name = "review_time")
    private LocalDateTime reviewTime;

    /**
     * 生效时间
     */
    @Column(name = "effective_time")
    private LocalDateTime effectiveTime;

    /**
     * 失效时间
     */
    @Column(name = "expiry_time")
    private LocalDateTime expiryTime;

    /**
     * 是否当前版本
     */
    @Column(name = "is_current")
    @Builder.Default
    private Boolean isCurrent = false;

    /**
     * 是否草稿版本
     */
    @Column(name = "is_draft")
    @Builder.Default
    private Boolean isDraft = false;

    /**
     * 备注
     */
    @Size(max = 1000, message = "备注长度不能超过1000个字符")
    @Column(name = "remarks", length = 1000)
    private String remarks;

    /**
     * 版本快照，JSON格式
     */
    @Column(name = "version_snapshot", columnDefinition = "LONGTEXT")
    private String versionSnapshot;

    /**
     * 变更详情，JSON格式
     */
    @Column(name = "change_details", columnDefinition = "LONGTEXT")
    private String changeDetails;

    /**
     * 版本标签
     */
    @Size(max = 500, message = "版本标签长度不能超过500个字符")
    @Column(name = "version_tags", length = 500)
    private String versionTags;

    /**
     * 记录创建时间
     */
    @Column(name = "created_time", nullable = false, updatable = false)
    private LocalDateTime createdTime;

    /**
     * 记录最后更新时间
     */
    @Column(name = "updated_time", nullable = false)
    private LocalDateTime updatedTime;

    /**
     * 创建人用户ID
     */
    @Size(max = 50, message = "创建人长度不能超过50个字符")
    @Column(name = "created_by", nullable = false, length = 50)
    private String createdBy;

    /**
     * 最后更新人用户ID
     */
    @Size(max = 50, message = "更新人长度不能超过50个字符")
    @Column(name = "updated_by", length = 50)
    private String updatedBy;

    /**
     * 乐观锁版本号
     */
    @Version
    @Column(name = "version", nullable = false)
    @Builder.Default
    private Integer version = 1;

    /**
     * 软删除标记
     */
    @Column(name = "is_deleted", nullable = false)
    @Builder.Default
    private Boolean isDeleted = false;

    /**
     * 删除时间
     */
    @Column(name = "delete_time")
    private LocalDateTime deleteTime;


    /**
     * 版本类型枚举
     */
    public enum VersionType {
        MAJOR("MAJOR", "主版本"),
        MINOR("MINOR", "次版本"),
        PATCH("PATCH", "补丁版本"),
        HOTFIX("HOTFIX", "热修复版本"),
        DRAFT("DRAFT", "草稿版本");

        private final String code;
        private final String description;

        VersionType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public String getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 版本状态枚举
     */
    public enum VersionStatus {
        DRAFT("DRAFT", "草稿"),
        PENDING("PENDING", "待审核"),
        APPROVED("APPROVED", "已批准"),
        REJECTED("REJECTED", "已拒绝"),
        ACTIVE("ACTIVE", "已生效"),
        EXPIRED("EXPIRED", "已过期"),
        DEPRECATED("DEPRECATED", "已弃用");

        private final String code;
        private final String description;

        VersionStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public String getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 变更类型枚举
     */
    public enum ChangeType {
        CREATE("CREATE", "创建"),
        UPDATE("UPDATE", "更新"),
        MODIFY("MODIFY", "修改"),
        DELETE("DELETE", "删除"),
        CONTENT("CONTENT", "内容变更"),
        METADATA("METADATA", "元数据变更"),
        STATUS("STATUS", "状态变更"),
        APPROVAL("APPROVAL", "审核变更");

        private final String code;
        private final String description;

        ChangeType(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public String getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }

    /**
     * 审核状态枚举
     */
    public enum ReviewStatus {
        PENDING("PENDING", "待审核"),
        IN_PROGRESS("IN_PROGRESS", "审核中"),
        APPROVED("APPROVED", "已通过"),
        REJECTED("REJECTED", "已拒绝"),
        CANCELLED("CANCELLED", "已取消");

        private final String code;
        private final String description;

        ReviewStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }

        public String getCode() {
            return code;
        }

        public String getDescription() {
            return description;
        }
    }
}